import type { AxiosRequestConfig } from "axios";
import { APP_VERSION_WEB, APP_VERSION_APP, RSA_PUBLIC_KEY, SIGN_ENABLED, SIGN_HEADER_NAME, TIMESTAMP_HEADER_NAME, APP_VERSION_HEADER_NAME, SIGN_SKIP_LIST, SIGN_URI_WITH_BASE_PREFIX, SIGN_DEBUG, PLAIN_DEBUG_HEADER_NAME } from "@/constants/signature";

// 仅提供函数签名与编排，不包含具体实现细节

export function shouldSkipSign(config: AxiosRequestConfig): boolean {
  const url = String(config.url || "");
  if (!SIGN_ENABLED) return true;
  if (!url) return true;
  const customSkip = (config as any).__skipSign === true || (config.headers && (config.headers as any).__skipSign === true);
  if (customSkip) return true;
  return SIGN_SKIP_LIST.some((rule) => {
    if (typeof rule === "string") return url.includes(rule);
    return rule.test(url);
  });
}

export function normalizePath(urlOrPath: string): string {
  // 提取 pathname，不含协议、域名与查询串；并保证以 / 开头
  try {
    const u = new URL(urlOrPath, "http://placeholder");
    return u.pathname || "/";
  } catch (_) {
    // 相对路径
    if (!urlOrPath) return "/";
    const hashIndex = urlOrPath.indexOf("#");
    const qIndex = urlOrPath.indexOf("?");
    const end = [hashIndex, qIndex].filter((i) => i >= 0).sort((a, b) => a - b)[0];
    const path = end >= 0 ? urlOrPath.slice(0, end) : urlOrPath;
    return path.startsWith("/") ? path : `/${path}`;
  }
}

/**
 * 计算用于签名的 URI：将 baseURL 的路径前缀与 config.url 合并，再取 pathname
 * - baseURL 为相对路径（/installer-admin）时，直接拼接
 * - baseURL 为绝对地址（http://host:port/app）时，使用 URL 解析后取 pathname
 */
export function getSignedPath(config: AxiosRequestConfig): string {
  const rawUrl = String(config.url || "");
  const base = String((config.baseURL || (config as any)?.baseURL || "") || "");
  const useBasePrefix = typeof (config as any).__signUseBasePrefix === "boolean"
    ? (config as any).__signUseBasePrefix
    : SIGN_URI_WITH_BASE_PREFIX;
  if (!base || !useBasePrefix) return normalizePath(rawUrl);
  try {
    if (/^https?:\/\//i.test(base)) {
      const full = new URL(`${base.replace(/\/$/, "")}/${rawUrl.replace(/^\//, "")}`);
      return full.pathname || normalizePath(rawUrl);
    }
    // 相对 baseURL，例如 /installer-admin
    const joined = `${base.replace(/\/$/, "")}/${rawUrl.replace(/^\//, "")}`;
    return normalizePath(joined);
  } catch {
    return normalizePath(rawUrl);
  }
}

export function buildPlain(appVersion: string, path: string, timestamp: number | string): string {
  return `${appVersion}.${path}/${String(timestamp)}`;
}

export function setSignHeaders(config: AxiosRequestConfig, signBase64: string, timestamp: number | string, appVersion?: string): void {
  config.headers = config.headers || {};
  if (signBase64) {
    (config.headers as any)[SIGN_HEADER_NAME] = signBase64;
  }
  (config.headers as any)[TIMESTAMP_HEADER_NAME] = String(timestamp);
  (config.headers as any)[APP_VERSION_HEADER_NAME] = appVersion || inferVersionByConfig(config);
  if (SIGN_DEBUG && (import.meta as any).env?.DEV) {
    const debugPlain = (config as any).__plain_for_debug as string;
    if (debugPlain) {
      (config.headers as any)[PLAIN_DEBUG_HEADER_NAME] = debugPlain;
    }
  }
}

export function getAppVersion(isApp: boolean): string {
  return isApp ? APP_VERSION_APP : APP_VERSION_WEB;
}

export function getPublicKey(): string {
  return RSA_PUBLIC_KEY;
}

function inferVersionByConfig(config: AxiosRequestConfig): string {
  const base = String((config.baseURL || (config as any)?.baseURL || "") || "");
  // 约定：包含关键字时按 App 端处理
  const isApp = /app|hems|installer\/web|platform/i.test(base);
  return isApp ? APP_VERSION_APP : APP_VERSION_WEB;
}


